#include "SceneManager.h"

const float SceneManager::RADIUS = 0.05;
const int SceneManager::MAX_ITEMS = 25;
const int SceneManager::REFRESH_TIME = 20;

SceneManager::SceneManager(int w, int h)
{
	my_x = 0; my_y = 0;
	window_h = h; window_w = w;
	my_rect_h = 0.1; my_rect_w = 0.1;
	segment = 16;
	bRect = true;
}


SceneManager::~SceneManager(void)
{

}

void SceneManager::my_setup() 
{
	items_falling.clear();
	items_ground.clear();
}

void SceneManager::my_display()
{
	/* clear the buffer */
	glClear(GL_COLOR_BUFFER_BIT) ;

	glColor3f(0,0,1) ; /* (Red, Green, Blue); so here we ask for Blue */
	for(list<Shape*>::iterator it = items_falling.begin(); it!=items_falling.end();it++) {
		(*it)->drawShape();
	}
	glutSwapBuffers();
	return ;
}

void SceneManager::my_timeout(int id)
{
	switch (id) {
	case 0:	//event id 0
		for(list<Shape*>::iterator it = items_falling.begin(); it!=items_falling.end();it++) {
			if((*it)->isStop()) 
				continue;
			(*it)->fallDown((((float)REFRESH_TIME)/1000), items); 
			if((*it)->isStop()) {	//if that unit reach the ground, add to list ground
				if((*it)->name.compare("RECT") == 0) {
					for(int i = (my_x/window_w-my_rect_w/2)*10; i<=(my_x/window_w + my_rect_w/2)*10;i++) {
						items[i].push_back(*it);
					}
				}
				else if((*it)->name.compare("CIRCLE") == 0) {
					for(int i = (my_x/window_w-RADIUS)*10; i<=(my_x/window_w + RADIUS)*10;i++) {
						items[i].push_back(*it);
					}
				}
			}
		}
		glutPostRedisplay();
		break;
	}
}

void SceneManager::my_keyboard(unsigned char c, int x, int y)
{
	switch (c) {  /* c is the key that is being hit */
	case 'c': 
		printf("C key is hit\n");
		break;
	case 'y': 
		printf("Y key is hit\n");
		break;
	case '+': 
		segment++;
		my_display();
		break;
	case '-':
		if(segment >3) {
			segment --;
			my_display();
		}
		break;
		/* and so on*/
	}
}

void SceneManager::my_idle(void) {
	return ;
}

void SceneManager::my_reshape(int w, int h) {
	/* define the viewport to be the entire window */
	glViewport (0, 0, w, h); 
	window_w = w;
	window_h = h;
	return;
}

void SceneManager::my_mouse(int b, int s, int x, int y) {
	switch (b) {            /* b indicates the button */
	case GLUT_LEFT_BUTTON:
		if (s == GLUT_DOWN)  {    /* button pressed */

		}
		else if (s == GLUT_UP) { /* button released */
			my_x = x; 
			my_y = window_h-y;
			Shape *newShape = NULL;
			if(items_falling.size() >= MAX_ITEMS) {	//if items number exceed the max, we delete the first object
				Shape *del = items_falling.front();
				if(del->name.compare("RECT") == 0) {
					for(int i = (del->getMinX())*10; i<=(del->getMaxX())*10;i++) {
						items[i].remove(del);
					}
				}
				else if(del->name.compare("CIRCLE") == 0) {
					for(int i = (del->getMinX())*10; i<=(del->getMaxX())*10;i++) {
						items[i].remove(del);
					}
				}
				delete del;
				items_falling.pop_front();
			}
			if(bRect) {
				newShape = new MRect(my_x/window_w-my_rect_w/2, my_y/window_h-my_rect_h/2, my_x/window_w + my_rect_w/2, my_y/window_h + my_rect_h/2);
				newShape->setColor(0,0,1);
				bRect = false;
			}
			else {		
				newShape = new MCircle(my_x/window_w,my_y/window_h,RADIUS,segment);
				newShape->setColor(1,0,0);
				bRect = true;
			}
			items_falling.push_back(newShape);
			glutPostRedisplay();
		}
		break;
	case GLUT_RIGHT_BUTTON:
		if (s == GLUT_DOWN)  {    /* button pressed */
			printf("Right button pressed\n");
		}
		else if (s == GLUT_UP) { /* button released */
			printf("Right button released\n");
		}
		break;
	case GLUT_MIDDLE_BUTTON:
		if (s == GLUT_DOWN)  {    /* button pressed */
			printf("Middle button pressed at %d %d\n", x, y);
		}
		else if (s == GLUT_UP) { /* button released */
			printf("Middle button released\n");
		}
		break;

	}
}